package com.wxxymakers.grademark.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wxxymakers.grademark.exception.ServiceException;
import com.wxxymakers.grademark.model.entity.WxItem;
import com.wxxymakers.grademark.model.entity.WxItemPlace;
import com.wxxymakers.grademark.model.entity.WxItemRank;
import com.wxxymakers.grademark.model.entity.WxItemRecord;
import com.wxxymakers.grademark.model.mapper.WxItemMapper;
import com.wxxymakers.grademark.model.mapper.WxItemRecordMapper;
import com.wxxymakers.grademark.utils.NumUtils;
import com.wxxymakers.grademark.utils.PageUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;

/**
 * @AUTHOR soft
 * @DATE 2018/12/29 19:34
 * @DESCRIBE
 */
@Service
@Slf4j
public class WxItemService {

    @Autowired
    private WxItemRecordMapper recordMapper;

    @Autowired
    private WxItemRankService itemRankService;

    @Autowired
    private WxItemPlaceService itemPlaceService;

    @Autowired
    private WxItemMapper mapper;

    private void saveRankPlace(Integer itemId, List<WxItemRank> ranks, List<WxItemPlace> places) {
        for (int i = 0; i < ranks.size(); i++) {
            WxItemRank rank = ranks.get(i);
            rank.setId(itemId + "_" + i);
            rank.setItemId(itemId);
            itemRankService.add(rank);
        }
        for (int i = 0; i < places.size(); i++) {
            WxItemPlace place = places.get(i);
            place.setId(itemId + "_" + i);
            place.setItemId(itemId);
            itemPlaceService.add(place);
        }
    }

    @Transactional
    public boolean add(WxItem item, List<WxItemRank> ranks, List<WxItemPlace> places) {
        if (NumUtils.lteZero(item.getPeopleNum())) item.setPeopleNum(1);
        item.setDatetime(new Date());
        if (mapper.insert(item) > 0) {
            this.saveRankPlace(item.getId(), ranks, places);
            return true;
        }
        return false;
    }

    @Transactional
    public boolean delete(int id) {
        QueryWrapper<WxItemRecord> wrapper =  new QueryWrapper<>();
        wrapper.lambda().eq(WxItemRecord::getItemId, id);
        List<WxItemRecord> records = recordMapper.selectList(wrapper);
        if (!CollectionUtils.isEmpty(records)) {
            throw new ServiceException("无法删除存在记录的项目！");
        }

        return mapper.deleteById(id) > 0 && itemRankService.deleteByIid(id)
                && itemPlaceService.deleteByIid(id);
    }

    /**
     * 强制删除 不论有没有被占用
     * @param id 项目id
     */
    @Transactional
    public boolean deleteF(int id) {
        QueryWrapper<WxItemRecord> wrapper =  new QueryWrapper<>();
        wrapper.lambda().eq(WxItemRecord::getItemId, id);
        int delete = recordMapper.delete(wrapper);
        log.info("级联删除记录共：{}条", delete);

        return mapper.deleteById(id) > 0 && itemRankService.deleteByIid(id)
                && itemPlaceService.deleteByIid(id);
    }

    /**
     * 项目修改 修改时对内部的项目是删除后重建
     */
    @Transactional
    public boolean change(WxItem item) {
        if (NumUtils.lteZero(item.getId())) {
            throw new ServiceException("修改项不存在！");
        }

        if (itemPlaceService.deleteByIid(item.getId()) && itemRankService.deleteByIid(item.getId())) {
            if (mapper.updateById(item) > 0) {
                this.saveRankPlace(item.getId(), item.getRanks(), item.getPlaces());
                return true;
            }
        }
        return false;
    }

    public WxItem byId(int id) {
        return mapper.selectByIdNJ(id);
    }

    public WxItem byIdJoin(int id) {
        return mapper.selectById(id);
    }

    public WxItem byName(String name) {
        WxItem item = new WxItem();
        item.setName(name);
        return mapper.selectOne(new QueryWrapper<>(item));
    }

    public Page<WxItem> page(int page, int limit, WxItem query) {
        QueryWrapper<WxItem> wrapper = new QueryWrapper<>(query);
        wrapper.orderByDesc("id");

        int total = mapper.selectCount(wrapper);
        if (total > 0) {
            List<WxItem> wxItems = mapper.selectPage(PageUtils.rowBounds(page, limit), wrapper).getRecords();
            return new PageImpl<>(wxItems, new PageRequest(page - 1, limit), total);
        }
        return null;
    }

    public List<WxItem> list(WxItem query) {
        QueryWrapper<WxItem> wrapper = new QueryWrapper<>(query);
        wrapper.orderByDesc("id");

        return mapper.selectList(wrapper);
    }
}
